package hikari.managers;

import com.gooddies.wiring.Wiring;
import com.gooddies.wiring.annotations.Wire;
import com.gooddies.wiring.annotations.WiringComponent;
import hikari.instruments.MoveInstrument;
import hikari.instruments.ObserveInstrument;
import hikari.instruments.PanInstrument;
import hikari.instruments.RotationInstrument;
import hikari.instruments.ScaleInstrument;
import hikari.managers.undo.Undo;
import java.util.HashMap;
import java.util.Map;
import javax.swing.SwingUtilities;

/**
 * @author sad
 */
@WiringComponent(singleton = true, lazy = true)
public class ActionManager {

    public static final String MOVE = "move";
    public static final String ROTATE = "rotate";
    public static final String SCALE = "scale";
    public static final String PAN = "pan";
    public static final String OBSERVE = "observe";
    public static final String UNDO = "undo";
    private Map<String, Runnable> actionMap = new HashMap<>();
    @Wire
    private Manager3D manager3D;
    @Wire
    private Undo undo;

    private ActionManager() {
        init();
    }

    private void init() {
        addAction(MOVE, new Runnable() {
            @Override
            public void run() {
                manager3D.setInstrument(Wiring.getComponent(MoveInstrument.class));
            }
        });

        addAction(ROTATE, new Runnable() {
            @Override
            public void run() {
                manager3D.setInstrument(Wiring.getComponent(RotationInstrument.class));
            }
        });

        addAction(SCALE, new Runnable() {
            @Override
            public void run() {
                manager3D.setInstrument(Wiring.getComponent(ScaleInstrument.class));
            }
        });
        addAction(PAN, new Runnable() {
            @Override
            public void run() {
                manager3D.setInstrument(Wiring.getComponent(PanInstrument.class));
            }
        });
        addAction(OBSERVE, new Runnable() {
            @Override
            public void run() {
                manager3D.setInstrument(Wiring.getComponent(ObserveInstrument.class));
            }
        });
        addAction(UNDO, new Runnable() {
            @Override
            public void run() {
                undo.undo();
            }
        });
    }

    public void addAction(String actionId, Runnable action) {
        if (actionMap.containsKey(actionId)) {
            System.err.println("[ActionManager.addAction] Action map already contain action [" + actionId + "] skip");
            return;
        }
        actionMap.put(actionId, action);
    }

    public void invokeAction(String action) {
        final Runnable runnable = actionMap.get(action);
        if (runnable == null) {
            System.err.println("Cannot find handler for action [" + action + "]");
            return;
        }

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                runnable.run();
            }
        });
    }
}
